#ifndef __auxmathH__
#define __auxmathH__

#include <math.h>
#include "vector.h"
#include "wtftypes.h"

#define SQR(x)	(x * x)

#ifndef M_PI
#define M_PI	3.14159
#endif

#define RADS_TO_DEGS(a)	(a * (180.0 / M_PI))
#define DEGS_TO_RADS(a) (a * (M_PI / 180.0))

#define maxf(a, b) (a > b ? a : b)
#define minf(a, b) (a < b ? a : b)

void initRandom();

/// Returns a random number in the interval [-1,1].
inline tScalar getRandomFloat() {
	return (float(rand()) / float(RAND_MAX / 2)) - 1;
};


template <class T, unsigned Dim>
struct Ray {
	typedef typename VectorType<T, Dim>::tType tVector;

	tVector	vPosition;
	tVector	vDirection;

	Ray() {};
	Ray(const tVector& vs, const tVector& ve):
		vPosition(vs), vDirection(ve) {};
};

typedef Ray<tScalar, 3>	tRay;
typedef Ray<int, 2>		iRay2D;

typedef struct Plane {
	tVector	vNormal;
	tScalar	fDistance;

	Plane() {};
	Plane(const tVector& n, tScalar d): vNormal(n), fDistance(d) {};
} tPlane;

/*
 * Stored in Radians
 */
class Angle
{
	public:
		Angle ();
		Angle (double a);
		~Angle();
		inline double inRads() { return angle; }
		inline double inDegs() { return RADS_TO_DEGS(angle); };
		void setInRads(double a);
		void setInDegs(double a);

		inline Angle addRads(double a) {
			return Angle(a + angle);
		}

		inline Angle addDegs(double a) {
			return Angle(DEGS_TO_RADS(a) + angle);
		}

		inline Angle operator + (const Angle& a) const{
			Angle x(angle + a.angle);
			return x;
		};

		inline Angle operator - (const Angle& a) const{
			Angle x(angle - a.angle);
			return x;
		};

		inline Angle operator * (const double s) const {
			Angle x(angle * s);
			return x;
		}

	private:
		double angle;

};

#endif
